#include "NetcdfExtract.h"
#include "NetcdfWrapper.h"

namespace OCPP {

	bool NetcdfExtract::extract2D(String fileName, String varName, const VolumeOptions& options, int desiredLevel)
	{
		NetcdfWrapper reader;
		try {
			if (!reader.open(fileName)) return false;
			reader.extract(varName, options, desiredLevel);
		}
		catch (...) {
			reader.close();
			return false;
		}
		return true;
	}

	bool NetcdfExtract::computeAndExtract2D(GridDataCompute gridDataCompute, const VolumeOptions& options, int desiredLevel)
	{
		std::map<String, std::shared_ptr<NetcdfWrapper> > ncNcWrapperList;
		std::vector<std::tuple<String, GridDataVec> > ncOutputListList;

		for (const auto& [fileName, varName] : gridDataCompute.computePairVec)
		{
			if (ncNcWrapperList[fileName] == nullptr)
			{
				ncNcWrapperList[fileName] = std::make_shared<NetcdfWrapper>();
				if (!ncNcWrapperList[fileName]->open(fileName))
				{
					OCPP_LOG_ERROR << fileName << " can't open.\n";
					return false;
				}
			}
			auto& ncWrapper = ncNcWrapperList[fileName];
			auto data = ncWrapper->read(varName, options, desiredLevel);
			ncOutputListList.push_back({ fileName, data });
		}

		if (ncOutputListList.size() == 0)
		{
			return false;
		}

		auto& [fileName, data] = ncOutputListList[0];

		size_t comp = data.size();

		for (size_t i = 0; i < comp; i++)
		{
			GridDataVec dataListCompute;
			for (auto& ncOuputList : ncOutputListList)
			{
				auto& [fileName, data] = ncOuputList;
				auto& gridData = data[i];
				gridData.read(options);
				dataListCompute.emplace_back(std::move(gridData));
			}

			GridData ncGridData = gridDataCompute.algorithm->onCompute(dataListCompute, options);
			options.getWriter().write(ncGridData, options);
		}

		return true;
	}

	bool NetcdfExtract::extract3D(String fileName, String varName, const VolumeOptions& options)
	{
		return extract2D(fileName, varName, options, -1);
	}

	bool NetcdfExtract::computeAndExtract3D(GridDataCompute gridDataCompute, const VolumeOptions& options)
	{
		return computeAndExtract2D(gridDataCompute, options, -1);
	}
}